Stefan Gentz
Adobe Employee
Stefan Gentz
Adobe Employee
Activity
Nov 18, 2024
06:50 AM
1 Upvote
Hi Andreas, could you please send the corrupt XTS file (the 1 kb one) to tcssup@adobe.com with me on CC (I'll send you a PM with my email) if you still have it? Then we can check what was wrong with it and check if we can build in a user-friendly warning message or so for corrupt XTS files 🙂
... View more
Jun 24, 2024
03:46 AM
2 Upvotes
Let’s go through it line by line. I have added comments to your script (// ...) to make it easier to understand. I have also added some console messages to help with debugging and changed some smaller things, e.g., in this line:
// Your code, note the space before the comma in "doc.TextSelection.end ,":
doc.Import (doc.TextSelection.end , filename, importParams, returnParams);
// Changed code:
doc.Import (doc.TextSelection.end, filename, importParams, returnParams);
Commented and updated code:
// Ensure SelectElement is defined
// Function to select an element (Assuming this is defined elsewhere in your script)
function SelectElement(doc, element) {
// Implementation of your SelectElement function
}
// Select the paragraph element
SelectElement(doc, para);
// Create and set the text range
var textRange = new TextRange;
textRange.beg.obj = textRange.end.obj = para;
textRange.beg.offset = 0;
textRange.end.offset = Constants.FV_OBJ_END_OFFSET;
// Apply text selection
doc.TextSelection = textRange;
// Get the text selection range
textRange = doc.TextSelection;
var pgf = doc.TextSelection.beg.obj;
var start = pgf.Start;
// Select the table element
SelectElement(doc, table);
// Cut the selected table
doc.Cut(0);
// Debugging: Check if Cut operation was successful
$.writeln("Table cut operation completed");
// Import parameters setup
var importParams = GetImportDefaultParams();
// Set the import type to XML
var i = GetPropIndex(importParams, Constants.FS_ImportAsType);
importParams[i].propVal.ival = Constants.FV_TYPE_XML;
// Set the file as an XML document and import anyway
i = GetPropIndex(importParams, Constants.FS_FileIsXmlDoc);
importParams[i].propVal.ival = Constants.FV_DoOK;
// Do not alert the user about failures
i = GetPropIndex(importParams, Constants.FS_AlertUserAboutFailure);
importParams[i].propVal.ival = 0;
// Do not notify API clients
i = GetPropIndex(importParams, Constants.FS_DontNotifyAPIClients);
importParams[i].propVal.ival = 1;
// Set how to import to "copy"
i = GetPropIndex(importParams, Constants.FS_HowToImport);
importParams[i].propVal.ival = Constants.FV_DoByCopy;
// Allocate return parameters
var returnParams = new PropVals() ;
// Add notification for user response to trigger set_shading
Notification(Constants.FA_Note_BackToUser, true);
// Debugging: Check if importParams are set correctly
$.writeln("Import parameters set: " + JSON.stringify(importParams));
// Perform the import
doc.Import(doc.TextSelection.end, filename, importParams, returnParams);
// Debugging: Check if import operation was successful
$.writeln("Import operation completed");
// Reapply paragraph start property
pgf.Start = start;
// Debugging: Final confirmation
$.writeln("Script execution completed.");
That given, I would suggest to break the code into functions, separate concerns, and add error handling so that the user also gets information what went wrong and why. Here is a complete rewrite of your code (note, that your "SelectElement" function needs to be present!):
// Function to select an element (Assuming this is defined elsewhere in your script)
function SelectElement(doc, element) {
// Implementation of your SelectElement function
}
// Function to get import parameters with desired settings
function getCustomImportParams() {
var importParams = GetImportDefaultParams();
// Helper function to set property value safely
function setPropVal(params, propConst, value) {
var index = GetPropIndex(params, propConst);
if (index !== Constants.FE_BadPropNum) {
params[index].propVal.ival = value;
} else {
$.writeln("Property not found: " + propConst);
}
}
// Set import parameters
setPropVal(importParams, Constants.FS_ImportAsType, Constants.FV_TYPE_XML);
setPropVal(importParams, Constants.FS_FileIsXmlDoc, Constants.FV_DoOK);
setPropVal(importParams, Constants.FS_AlertUserAboutFailure, 0);
setPropVal(importParams, Constants.FS_DontNotifyAPIClients, 1);
setPropVal(importParams, Constants.FS_HowToImport, Constants.FV_DoByCopy);
return importParams;
}
// Main function to execute the script logic
function main() {
// Ensure SelectElement is defined and usable
if (typeof SelectElement !== "function") {
throw new Error("SelectElement function is not defined");
}
// Select the paragraph element
SelectElement(doc, para);
// Create and set the text range
var textRange = new TextRange();
textRange.beg.obj = textRange.end.obj = para;
textRange.beg.offset = 0;
textRange.end.offset = Constants.FV_OBJ_END_OFFSET;
// Apply text selection
doc.TextSelection = textRange;
// Get the text selection range
textRange = doc.TextSelection;
var pgf = doc.TextSelection.beg.obj;
var start = pgf.Start;
// Select the table element
SelectElement(doc, table);
// Cut the selected table
doc.Cut(0);
// Debugging: Check if Cut operation was successful
$.writeln("Table cut operation completed");
// Get custom import parameters
var importParams = getCustomImportParams();
// Allocate return parameters
var returnParams = new PropVals();
// Add notification for user response to trigger set_shading
Notification(Constants.FA_Note_BackToUser, true);
// Debugging: Check if importParams are set correctly
$.writeln("Import parameters set: " + JSON.stringify(importParams));
// Perform the import
doc.Import(doc.TextSelection.end, filename, importParams, returnParams);
// Debugging: Check if import operation was successful
$.writeln("Import operation completed");
// Reapply paragraph start property
pgf.Start = start;
// Debugging: Final confirmation
$.writeln("Script execution completed");
}
// Execute the main function
try {
main();
} catch (e) {
$.writeln("Error: " + e.message);
}
Encapsulation and Modularization:
The getCustomImportParams function encapsulates the logic for setting up import parameters, making the code more modular.
The setPropVal helper function sets property values safely and logs a message if the property is not found.
Error Handling:
Added a check to ensure the SelectElement function is defined. It is currently not part of this script and is missing in your code example.
Wrapped the execution of the main function in a try-catch block to handle any runtime errors gracefully.
Code Clarity and Maintainability:
Used meaningful function and variable names to improve readability.
Added comments to explain the purpose of each code section.
The setPropVal function abstracts the repetitive task of setting property values, reducing code duplication.
Debugging and Logging:
Added debug messages using $.writeln to trace the execution flow and capture the state of important variables.
This version implements some best practices for coding in ExtendScript. It should make it more robust, maintainable, and easier to understand. Let us know if this helps.
... View more
Apr 30, 2024
06:39 AM
Unfortunately, as of now, I cannot comment on future scripting plans. But what I see is that there is a general move towards UXP within Adobe …
... View more
Apr 30, 2024
05:34 AM
1 Upvote
Feedback taken, @Russ Ward and @frameexpert.
Generally said, with Updates that include library updates (like the security updates in this release), it is often (if not always) necessary to update the FDK clients. The library updates are mentioned in the release notes.
Unfortunately Update 4 was released a couple of days before the FDK Update was released. This is obviously not ideal, completely agree. Ideally there should have been a Prerelease for Update 4 including the FDK. We will make sure to have this ready in time for the next Update.
Regarding the future of FrameMaker: Our main focus this year is on the ARM release which is a massive undertaking as it goes deep into the core of FM and needs extensive testing as well. Once this is done, I’m confident, the doors are wide open for a bright future for FM in the coming years 🙂
... View more
Apr 30, 2024
05:19 AM
@Nandini Krishna, I guess https://helpx.adobe.com/in/framemaker/kb/framemaker-downloads.html is not updated yet, and the download link is pointing to 17.0.2 FDK, not the 17.0.4 FDK.
Can you please confirm that the correct link to the latest 17.0.4 FDK for Update 4 is this one:
https://download.adobe.com/pub/adobe/framemaker/win/17.0.4/FDK2022.zip
... View more
Apr 14, 2024
11:54 AM
Sorry, I had accidentally copy and pasted text from the post as the URL 🤦🏼, so it could not work!
I have fixed the link in the post, so if you refresh this page, it should work.
Here is also the link:
https://freefrontend.com/css-lists/
It's just one of many websites out there with creative list stylings. I found this one useful for inspiration and because it provides links to the source code of the given examples. Looking at them helped me alot to get a deeper understanding of list formatting.
Of course, in the world of CSS there are often many ways to achieve visually identical results.
... View more
Apr 14, 2024
08:03 AM
I tried to visualize it … hope that helps:
... View more
Apr 14, 2024
07:47 AM
Dear Jennifer,
I can sense your frustration, and it's completely understandable. Transitioning from the familiar territory of Microsoft Word to the vast ocean of HTML and CSS can be quite a challenge. I'll try to help with some analogies to the world of Word as well. The base for all this is HTML and CSS, which gives almost endless possibilities for formatting lists (you can find some beautiful examples of list formatting ideas for example here).
Let's go through some of the terms you see in the user interface and explain what they mean.
Let me try to break them down:
Indent: Imagine the left margin in Word. In CSS, RoboHelp’s list Indent is akin to setting the left margin for your list. If it’s set to 40 px, think of it as the whole list starting 40 pixels from the left side (your text flow, or, e.g., the left border of a table cell). It's your list's personal space from the document's edge. Following, for sub lists, it’s the indent for the sub list items compared to the parent list item’s indent.
Prefix Width: This sets aside space for the bullet or number – like creating a special reserved space for it. With a Prefix Width of 50px, each bullet or number gets a 50 pixel-wide spot to sit comfortably before your text starts.
Horizontal spacing (←→): This defines an additional space after Prefix Width ("Prefix Gap"). That is, it’s the space right after the space reserved for the list marker (Prefix Width) before the text content of the list item starts. It's like the space you'd add in Word after a bullet point before the text follows. E.g., with Prefix Gap set to 20px, there's a 20-pixel "bridge" between the end of the list marker space and the start of your text.
Vertical Spacing (↑↓): A Vertical Spacing of, e.g., 20px creates a consistent (vertical) 20-pixel space between each of your list items, akin to setting a fixed space after each paragraph in Word.
Under "Layout" you will also find Margin and Padding, that give you additional control over the spacing of lists:
Margin refers to the space outside element. It's like the buffer zone between your list (or list item) and other items in your content. Think of the margin in CSS like the margins you set in a Word document; it's the space around the outside of your content (like a paragraph, list, list item, etc.) that separates it from other content. So, in a web page, a margin determines how much space is between the border of your list and any other items.
Padding is the space between the content (your text) and the border of an element. Think of it like a passpartout in a picture frame. Padding is similar to adjusting the space between the border of a text box and the text inside this text box in Word. It "cushions" the content from touching the border directly. In a web page, increasing padding will make your content appear more inset, giving it room to breathe inside its own boundary.
I hope this helps you feel a little bit more at home with list styling in RoboHelp. If anything is still unclear or if you need more guidance, please let us know. We’re here to help you set sail smoothly on this new adventure.
I just wanted a list that starts 1/2" in from the left margin followed by a tab space of 1/2" at which point my text should begin and I want the 2nd line to wrap right up under where the 1st line text begins.
For your specific case, here's a simple approach you might want to try:
Set the Indent to create the "0.5 in" space from the left margin.
Adjust Prefix Width to control the space reserverd for the bullet or number (give it enough also for two-digit numbers).
Adjust horizontal Spacing (←→) to reserve space between the space reserved for the bullet or number and the list item content.
Use vertical Spacing (↑↓) if you want to increase or decrease the space between the list items.
Here is an additional "visualization":
[Indent: 0.5in] [Prefix Width: 50px] [Horizontal Spacing (←→): 10px] [List content]
This would make the list number or bullet start 0.5 inch indent to the right, followed by 50px reserved space for the numer or bullet, followed by 10px "gap" before the list item content starts.
Keep in mind, the changes you make here should be previewed in the "Preview" window, but sometimes the changes may not appear until you save and view the document outside the style editor.
If you are still not seeing the changes you expect, it could be due to other overriding styles or settings. More details to understand the exact formatting you are trying to achieve and what exactly is not working, might help us to help you 🙂
I hope this helps you get a bit closer to the list format you're aiming for.
Warm regards, Stefan
... View more
Jan 23, 2024
02:57 AM
1 Upvote
Regarding different backgrounds – yes, that’s possible. In a nutshell:
Assign a class to the body of the topics
Style it as per your needs.
So, in the topic, you would give the body of a topic a specific class like "concept", "topic", "troubleshooting" (or whatever fits for you). So, in the source code of your topic it would look like this:
<body class="troubleshooting">
<!-- the content of your topic -->
</body>
Then in your CSS you can style the <body> element with class troubleshooting like this:
body.troubleshooting {
background-color: red;
}
Of course, you can apply all the CSS styling to the body like background-color, background-image, etc. (more more info, see here.)
... View more
Nov 30, 2023
07:17 AM
You might want to have a look at Adobe Experience Manager Guides, which is the CCMS (Component Content Management System) in the Adobe Experience Manager ecosystem. AEM Guides is a bit like “the big enterprise version” of RoboHelp. If you are familiar with RoboHelp, you will quickly become familiar with AEM Guides.
The Adobe Experience Manager ecosystem consists of various modules:
AEM Assets (for digital asset management)
AEM Sites (for web content management)
Adobe Analytics (for comprehensive analysis of the customer journey)
AEM Guides (for knowledge content, technical documentation, etc.), and many more.
However, you will no longer need RoboHelp, as you would use AEM Guides instead of RoboHelp.
P.S.: I guess I do not need to mention, that such a cloud-native enterpise solution with extremely comprehensive and powerful functionalities comes with a very different price tag than a desktop-based, single-user solution like RoboHelp.
... View more
Nov 23, 2023
06:18 AM
1 Upvote
If you have an enterprise account, you also have an Adobe Account Manager assigned to your company, depending on your team size maybe even a dedicated AM from the Technical Communication team. If you have no way to figure out internally (e.g., IT, purchasing) who your assinged AM is, you can reach out to tcssup@adobe.com and they will be happy to assist you.
Might also work for you: If you cannot file tickets in the bug tracker, you can also just simply create a free Adobe ID on https://account.adobe.com/ which would then enable you again to create tickets on https://tracker.adobe.com.
... View more
Nov 23, 2023
06:07 AM
1 Upvote
Yes, like @Jeff_Coatsworth said, this is a typical task for a CCMS specialized on technical content with structured content like Adobe Experience Manager Guides.
... View more
Nov 07, 2023
08:39 AM
On investigating this further with RoboHelp 2022.3., I can confirm that there is a bug related to bookmark handling in specific scenarios.
I have tested this scenario:
<p>Bookmark: <a id="ThisIsBookmark1"></a></p>
<p>Bookmark: <a id="ThisIsBookmark2"></a>.</p>
<p><a id="ThisIsBookmark3"></a></p>
<a id="ThisIsBookmark4"></a>
Resulting translation (here: German):
<p>Lesezeichen: </p>
<p>Lesezeichen: .</p>
<p><a id="ThisIsBookmark3"></a></p>
<a id="ThisIsBookmark4"></a>
As you can see, in the first two cases, the bookmark gets lost, and in the other two cases it remains.
This might help you as an intermediate workaround until the bug is fixed.
I have created a ticket for this, that you can track here: RH-12164.
... View more
Nov 07, 2023
06:25 AM
The XLIFF only contains the translatable text extracted from the source document. It is not a complete representation of the full HTML-DOM, and XLIFF is not meant to represent that. That is, if your bookmark does not contain translatable text (and an ID is not meant for translation), it will not show up in the XLIFF-Structure.
At the beginning of the XLIFF file you will find the full HTML document in Base64 encoding. The XLIFF tree then contains the translatable strings, identifiable against the HTML with the ID attributes which gives the full XPATH to the corresponding element in the (embedded) HTML file. When importing the translated XLIFF, the translated strings are injected back into the HTML file embeded in the XLIFF file.
... View more
Oct 11, 2023
04:08 AM
I have edited my reply above to cover the doc var problem and also added code to jump to the orphaned marker.
Please try and let me know if it works.
... View more
Oct 11, 2023
03:45 AM
Three suggestions:
Instead of using two separate arrays for numXRefTextPaths and numMTextPaths , you can use an array of objects for the markers. This way, you can store both the ID and the marker object itself, which will make it easier to jump to the orphaned markers later.
Use the indexOf method to check if a marker ID exists in the cross-references array.
There's a potential issue. The variable doc is defined inside the loop where you're iterating through the book components. However, when you're trying to jump to the orphanedMarker later on, the doc variable might not be pointing to the correct document where the orphanedMarker is located. I suggest to store the document reference along with each marker.
main();
function main() {
var xRefIDs = [];
var mTextMarkers = [];
var book = app.ActiveBook;
if (!book.ObjectValid()) {
book = app.FirstOpenBook;
}
var comp = book.FirstComponentInBook;
while (comp.ObjectValid()) {
comp.ComponentIsSelected = true;
if (comp.ComponentType == Constants.FV_BK_FILE) {
var doc = OpenFile(comp.Name);
if (doc.ObjectValid() == true) {
var crXRefText = doc.FirstXRefInDoc;
while (crXRefText.ObjectValid()) {
var id_number = crXRefText.XRefSrcText.substr(0, 5);
xRefIDs.push(id_number);
crXRefText = crXRefText.NextXRefInDoc;
}
var crMText = doc.FirstMarkerInDoc;
while (crMText.ObjectValid()) {
if (crMText.MarkerText.match(/^[0-9]{5}/)) {
var cr_number = crMText.MarkerText.substr(0, 5);
mTextMarkers.push({
id: cr_number,
marker: crMText,
document: doc // Store the document reference
});
}
crMText = crMText.NextMarkerInDoc;
}
} else {
alert("Book cannot be found.\nRun the script again.");
return;
}
}
comp.ComponentIsSelected = false;
comp = comp.NextBookComponentInDFSOrder;
}
// Generate lists of IDs for the alert
var xRefIDList = xRefIDs.join(", ");
var mTextIDList = mTextMarkers.map(function(obj) { return obj.id; }).join(", ");
alert("Following cross-references were found:\n\n"
+ "\n\nXRefs ID: " + xRefIDList
+ "\n\nMText ID: " + mTextIDList
);
// Identify and jump to orphaned markers
for (var i = 0; i < mTextMarkers.length; i++) {
if (xRefIDs.indexOf(mTextMarkers[i].id) === -1) {
var orphanedMarker = mTextMarkers[i].marker;
alert("Orphaned target mark: " + orphanedMarker.MarkerText);
// Jump to the orphanedMarker
var orphanedDoc = mTextMarkers[i].document;
var textLoc = orphanedMarker.TextLoc;
var textSel = new TextSelection();
textSel.beg = textLoc;
textSel.end = textLoc;
orphanedDoc.TextSelection = textSel;
orphanedDoc.ScrollToText(textSel); // This will ensure the marker is visible in the FrameMaker window
// If you want to pause after each jump (e.g., to allow the user to review the marker),
// you can introduce a confirmation dialog here, like:
if (!confirm("Found an orphaned marker. Continue searching?")) {
break; // This will exit the loop if the user clicks "Cancel"
}
}
}
}
This approach should be more efficient in ExtendScript and should allow you to identify and jump to orphaned markers in Adobe FrameMaker.
... View more
Oct 02, 2023
03:57 AM
What is the relationship between the FrameMaker files and the XML files? Do they contain the same content?
Are the FrameMaker files structured FrameMaker files? Do they "load" the XML files into templates? We will need more information from you to get a better idea.
... View more
Oct 02, 2023
02:54 AM
Hm, never heard this one before. What does the console/report panel of the XLIFF export say? Also, are you talking here about trying to produces XLIFF from the FrameMaker, or from the XML files? Your related (almost identical) discussion: https://community.adobe.com/t5/framemaker-discussions/framemaker-2022-translate-with-xml-file/m-p/14126831
... View more
Oct 02, 2023
02:51 AM
It’s unclear to me what you mean with “the original English FrameMaker files together with the XML files”. Can you explain that a little bit more? I do not understand why you have both FrameMaker AND XML files.
Also, I do not understand why your translators insist on translating the XML files, instead of XLIFF? I’m not aware of ANY professional translation tool, that does not support (and prefers) XLIFF. Also, it does not matter if you workflow is FrameMaker-files-based or XML-files-based – in both scenarios a modern translation workflow should always be XLIFF-based.
... View more
Oct 02, 2023
02:39 AM
You are upsolutely right, @Amebr. Thanks for spotting. Of course it should have been div.wide-table {} , not div#wide-table {} .
I suggest to use class, not id: You can assign a class to many elements (that is, you can have multiple <div class="wide-table">(...)</div> in your document), but you can only have an id once (that is, <div id="wide-table">(...)</div> would be only allowed once in a document).
... View more
Sep 28, 2023
02:21 AM
You could try the following:
Wrap the table in a div container like this:
<div class="wide-table">
<table>
</table>
</div>
Then create a css for the div:
div#wide-table {
padding: 0px;
max-width: 100%;
/* or:
max-width: calc(100% - 20px);
while 20px can be any value to reduce the max-width
and make the div fit to the desired maximum width;
*/
overflow-x: auto;
}
This should (in theory) make the content of the div (here: the table) horizontally scrollable (autoscroll-x:auto).
... View more
Sep 01, 2023
05:49 AM
Just for completeness: "Generate a miniature table of contents" in the FrameMaker Online Help.
... View more
Jul 05, 2023
06:59 AM
1 Upvote
If it only happens with one language but not with others, it’s likely that there is an issue with the translated files. From the screenshots of the XLIFF files, I cannot immediately see a problem, they seem to be fine.
You can try to drill down to the problem by first importing one translated file, than the next, then the third, and so on, until you reach at the file where it "hangs". (Or is it just the one in your screenshot ("Top_Bar") that hangs?
... View more
May 12, 2023
08:21 AM
2 Upvotes
These recordings were made with the old Connect generation. Looks like they don't play in the new Adobe Connect generation.
I was able to get the entire recording, including Audio, with the "Adobe Connect Classic" app.
I downloaded the Installer from here and then run the Connect Classic app. Just put the URL of the session recordings in the "Enter the Adobe Connect meeting, seminar or content URL to join." field and click "Continue".
... View more
May 11, 2023
07:55 AM
2 Upvotes
The registration for webinar (recordings) is availabe for five years and gets closed after that. The two mentioned webinars are from 2015 (that is, even before I started at Adobe), so their “life time” ended two years ago.
However, I was able to find the recordings in the archive and have reactivated them for you. Here are the two deep links to the recordings (no registration required):
FrameMaker: How to write your own ExtendScript, Part 1
FrameMaker: How to write your own ExtendScript, Part 2
Enjoy 😀
... View more
Apr 18, 2023
01:15 PM
Hi Bob,
This short video about AEM Guides gives a quick overview: https://youtu.be/j0X5fh0KUMU
This short video gives a quick impression of what Creatives will be able to do with Adobe Firefly: https://youtu.be/DvBRj--sUMU
This page hopefully answers some first questions about copyright questions regarding Firefly: https://helpx.adobe.com/stock/contributor/help/firefly-faq-for-adobe-stock-contributors.html
Hope that hellps. Happy to anwer any questions about AEM Guides.
... View more
Apr 18, 2023
09:51 AM
1 Upvote
Maybe you overestimate the power of a marketing team, even if I sometimes wish you were right 😉
Regarding a "cloud version of FrameMaker": In a way, yes, Adobe has done that, even if it goes far beyond a "cloud version of FrameMaker": With Adobe Experience Manager Guides, Adobe offers a cloud-native CCMS for all kinds of long-form knowledge content including technical documentation, help & support content, knowledge base content, policies & procedures, legal content, reports, etc.. It’s a comprehensive, cloud solution for authoring, managing, reviewing, translating and omni-channel publishing structured content.
... View more
Apr 04, 2023
06:47 AM
I'm also not sure, if I completely understand the requirement, but I guess dynamic content could do what you want. You can have one project with different different types of content and then mark these sections with conditional tags. End-users visiting the published page can then select which content they want to see based on selecting checkboxes.
Have a look here: https://helpx.adobe.com/robohelp/using/basics-of-conditional-content.html
... View more
Mar 31, 2023
05:55 AM
1 Upvote
+1 to what Peter wrote 😉
You can also add a custom JavaScript file to a specific topic by adding it in the <head> element of your HTML source code or at the end before the closing </body> tag depending on what makes sense for your JavaScript.
Like this:
<script type="text/javascript" src="path/to/your/javascript-file.js"></script>
... View more
Mar 21, 2023
04:50 PM
1 Upvote
I have checked with the product team, and it is a known bug that appears in specific scenarios. They are already working on fixing it and an update will be made available probably next week.
... View more